package org;

import java.util.ArrayList;

import org.entities.Block;
import org.entities.EnemyTank;
import org.entities.Entity;
import org.entities.Tank;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Input;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.tiled.TiledMap;

/**
 *
 */
public class GameState extends BasicGameState {
	
	float mapX = 0;
	float mapY = 0;
	public int mapWidth;
	public int mapHeight;
	
	ArrayList entities = new ArrayList();
	
	Tank tank;
	
	public Image tankBaseImage;
	public Image tankTurretImage;
	
	public Image enemyTankBaseImage;
	public Image enemyTankTurretImage;
	
	TiledMap tilemap;
	
	Input input;
	
	/** The ID given to this state */
	public static final int ID = 0;
	
	public int getID() {
		return ID;
	}
	
	/**
	 * @see org.newdawn.slick.BasicGame#init(org.newdawn.slick.GameContainer)
	 */
	public void init(GameContainer container, StateBasedGame stateContainer) throws SlickException {
		
		input = container.getInput();
		
		// load images
		tankBaseImage = new Image ("data/tankbase.png");
		tankTurretImage = new Image ("data/tankturret.png");
		
		enemyTankBaseImage = new Image ("data/redbase.png");
		enemyTankTurretImage = new Image ("data/redturret.png");
		
		// load background
		tilemap = new TiledMap("data/tile1.tmx");
		mapWidth = tilemap.getWidth() * tilemap.getTileWidth();
		mapHeight = tilemap.getHeight() * tilemap.getTileHeight();
		
		// add obsticles from the background
		for (int j = 0; j < tilemap.getHeight(); j++) {
			for (int i = 0; i < tilemap.getWidth(); i++) {
				// add small blocks as obsticles
				if (tilemap.getTileId(i, j, 1) == 31 || 
					tilemap.getTileId(i, j, 1) == 48 || 
					tilemap.getTileId(i, j, 1) == 49 || 
					tilemap.getTileId(i, j, 1) == 39 ||
					tilemap.getTileId(i, j, 1) == 50) {
					entities.add(new Block(this, i * tilemap.getTileWidth(), j * tilemap.getTileHeight()));
				}
			}
		}
		
		tank = new Tank(this, 400, 320);
		
		entities.add(tank);
		
		for (int i = 0; i < 10; i++) {
			entities.add(new EnemyTank(this, (int)(Math.random() * (tilemap.getTileWidth() * tilemap.getWidth())), 
											 (int)(Math.random() * (tilemap.getTileHeight() * tilemap.getHeight()))));
		}
	}
	
	/**
	 * @see org.newdawn.slick.BasicGame#update(org.newdawn.slick.GameContainer, int)
	 */
	public void update(GameContainer container, StateBasedGame stateContainer, int delta) {
		
		tank.targetRotation(readKeys());
		
		
		int turretRotate = (int)Math.toDegrees(Math.atan2(tank.getY() - input.getMouseY() + mapY, 
														  tank.getX() - input.getMouseX() + mapX)) - 90;
		tankTurretImage.setRotation(turretRotate);
		
		// update entities
		for (int i = 0; i < entities.size(); i++) {
			Entity entity = (Entity) entities.get(i);
			entity.update(delta);
		}
		
		// set view to follow tank
		mapX = 400 - tank.getX();
		mapY = 320 - tank.getY();
		
		if (mapX > 0) {
			mapX = 0;
		}
		
		if (mapY > 0) {
			mapY = 0;
		}
			
		if (mapX < -(mapWidth - 800)) {
			mapX = -(mapWidth - 800);
		}
		
		if (mapY < -(mapHeight - 640)) {
			mapY = -(mapHeight - 640);
		}
	}
	
	public boolean collisionDetection(Entity entity) {
		
		for (int i = 0; i < entities.size(); i++) {
			Entity entity1 = (Entity) entities.get(i);
			
			if (entity != entity1) {
				if (entity.isCollisionWith(entity1)) {
					return entity.collidedWith(entity1);
				}	
			}
		}
		
		return false;
	}
	
	/**
	 * @see org.newdawn.slick.BasicGame#render(org.newdawn.slick.GameContainer, org.newdawn.slick.Graphics)
	 */
	public void render(GameContainer container, StateBasedGame stateContainer, Graphics g) {
		g.translate(mapX, mapY);
		tilemap.render(0, 0);
		g.resetTransform();
		
		g.translate(mapX, mapY);
		
		for (int i = 0; i < entities.size(); i++) {
			Entity entity = (Entity) entities.get(i);
			entity.draw(g);
		}
	}
	
	public int readKeys() {
		
		boolean upPressed = false;
		boolean downPressed = false;
		boolean leftPressed = false;
		boolean rightPressed = false;
		
		if (input.isKeyDown(Input.KEY_UP) || input.isKeyDown(Input.KEY_W)) {
			upPressed = true;
		}
		else if (input.isKeyDown(Input.KEY_DOWN) || input.isKeyDown(Input.KEY_S)) {
			downPressed = true;
		}
		
		if (input.isKeyDown(Input.KEY_RIGHT) || input.isKeyDown(Input.KEY_D)) {
			rightPressed = true;
		}
		if (input.isKeyDown(Input.KEY_LEFT) || input.isKeyDown(Input.KEY_A)) {
			leftPressed = true;
		}
		
		if (upPressed && rightPressed) {
			return 45;
		}
		else if (upPressed && leftPressed) {
			return 315;
		}
		else if (upPressed) {
			return 0;
		}
		else if (downPressed && rightPressed) {
			return 135;
		}
		else if (downPressed && leftPressed) {
			return 225;
		}
		else if (downPressed) {
			return 180;
		}
		else if (rightPressed) {
			return 90;
		}
		else if (leftPressed) {
			return 270;
		}
		else return -1;
	}
}